package com.jrx.anytxn.investor.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.function.UncheckedFunction;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.common.uitl.CollectorsUtils;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.investor.bean.*;
import com.jrx.anytxn.investor.constant.TransBizConstant;
import com.jrx.anytxn.investor.entity.*;
import com.jrx.anytxn.investor.mapper.ext.*;
import com.jrx.anytxn.investor.service.IInvestorAccountService;
import com.jrx.anytxn.investor.service.IInvestorDealDelqService;
import com.jrx.anytxn.investor.service.IInvestorLoanChangeService;
import com.jrx.anytxn.investor.service.IInvestorStrategySelector;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.entity.PrInvestorPenaltyRate;
import com.jrx.anytxn.param.service.investor.IPrInvestorPenaltyRateService;
import com.jrx.anytxn.transaction.bean.DelqParamBean;
import com.jrx.anytxn.transaction.bean.DelqSaveBean;
import com.jrx.anytxn.transaction.service.IDealDelqService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 延滞处理操作类
 *
 * @author liuyang
 * @date 2020-05-26
 **/
@Service
public class InvestorDealDelqServiceImpl implements IInvestorDealDelqService {

    private static final Logger logger = LoggerFactory.getLogger(InvestorDealDelqServiceImpl.class);

    @Autowired
    private ISegmentService segmentService;
    @Autowired
    private IInvestorAccountService accountService;
    @Autowired
    private IPrInvestorPenaltyRateService prPenaltyRateTableService;
    @Autowired
    private IInvestorStrategySelector strategySelector;
    @Autowired
    private IDealDelqService dealDelqService;
    @Autowired
    private IInvestorLoanChangeService loanChangeService;


    /**
     * 构建延滞处理列表
     *
     * @param plan         还款计划
     * @param businessDate 业务日期
     * @return BtInvestorDelqList 延滞待处理列表
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-26
     */
    @Override
    public BtInvestorDelqList buildBtDelqList(AmRepaymentPlanInvestorInfo plan, Date businessDate) throws TxnBizException {
        BtInvestorDelqList btDelqList = new BtInvestorDelqList();
        BeanMapping.copy(plan, btDelqList);
        try {
            btDelqList.setId(segmentService.getId(TransBizConstant.BT_INVESTOR_DELQ_LIST));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        btDelqList.setBusinessDate(businessDate);
        btDelqList.setUpdateBy(TransBizConstant.SYS_OPRATE);
        btDelqList.setCreateTime(null); // 创建时间设置为空
        btDelqList.setUpdateTime(null); // 更新时间设置为空
        return btDelqList;
    }

    /**
     * 构建延滞处理列表
     *
     * @param delq         延滞信息
     * @param businessDate 业务日期
     * @return BtInvestorDelqList 延滞待处理列表
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-26
     */
    @Override
    public BtInvestorDelqList buildBtDelqList(AmDelinquencyInvestorInfo delq, Date businessDate) throws TxnBizException {
        BtInvestorDelqList btDelqList = new BtInvestorDelqList();
        BeanMapping.copy(delq, btDelqList);
        try {
            btDelqList.setId(segmentService.getId(TransBizConstant.BT_INVESTOR_DELQ_LIST));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        btDelqList.setBusinessDate(businessDate);
        btDelqList.setUpdateBy(TransBizConstant.SYS_OPRATE);
        btDelqList.setCreateTime(null); // 创建时间设置为空
        btDelqList.setUpdateTime(null); // 更新时间设置为空
        return btDelqList;
    }

    /**
     * 延滞处理
     *
     * @param bean
     * @return InvestorDelqSaveBean 延滞处理更新信息
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-26
     */
    @Override
    public InvestorDelqSaveBean dealDelq(InvestorDealDelqBean bean) throws TxnException {
        InvestorDelqSaveBean delqSaveBean = new InvestorDelqSaveBean();
        AmRepaymentPlanInvestorInfo repaymentPlanInfo = bean.getRepaymentPlanInfo();
        Date businessDate = bean.getBusinessDate();
        String customerId = repaymentPlanInfo.getCustomerId();
        String tenantId = repaymentPlanInfo.getTenantId();
        //逾期天数    当前处理日（today） - 还款日（payment_due_date） + 1
        Integer delqDays = DateUtils.getDiffDays(repaymentPlanInfo.getPaymentDueDate(), businessDate) + 1;

        //更新还款计划   逾期天数  状态
        AmRepaymentPlanInvestorInfo updatePlan = new AmRepaymentPlanInvestorInfo();
        updatePlan.setId(repaymentPlanInfo.getId());
        updatePlan.setCustomerId(repaymentPlanInfo.getCustomerId());
        updatePlan.setTenantId(repaymentPlanInfo.getTenantId());
        updatePlan.setDelqDays(delqDays);

        //当前还款计划为正常状态
        if (TransBizConstant.LOAN_PLAN_STATUS_1.equals(repaymentPlanInfo.getPlanStatus())) {
            AmLoanMainInvestorInfo amLoanMainInfo = bean.getLoanMain();
            AmLoanAccountInvestorInfo amLoanAccountInfo = bean.getLoanAcct();

            InvestorDelqSaveBean noDebtBean = this.dealNoDebt(bean);
            if (null != noDebtBean) {
                return noDebtBean;
            }

            //生成延滞账户
            AmDelinquencyInvestorInfo delq = accountService.generateDelinquencyInfo(amLoanMainInfo, repaymentPlanInfo, businessDate, delqDays);
            delqSaveBean.setInsertDelq(delq);

            //生成罚息/复利累计账户
            PrInvestorPenaltyRate prPenaltyRateTable = prPenaltyRateTableService.findPrInvestorPenaltyRate(amLoanMainInfo.getTenantId(), amLoanMainInfo.getInvestorPenaltyTableId());
            DelqParamBean delqParamBean = dealDelqService.buildDqlqAccountBean(amLoanMainInfo.getTenantId(), amLoanMainInfo.getDelqTableId());
            List<AmInterestAccrualInvestorInfo> accrualList = accountService.castPenAndComAccrualAccount(repaymentPlanInfo, amLoanMainInfo, amLoanAccountInfo, prPenaltyRateTable, delqParamBean, null);
            delqSaveBean.setAccrualList(accrualList);

            //更新交易账户
            List<AmAccountMainInvestorInfo> acctList = bean.getAcctList();
            if (CollectionUtils.isNotEmpty(acctList)) {
                List<AmAccountMainInvestorInfo> updateList = acctList.stream().map(
                        acct -> {
                            AmAccountMainInvestorInfo updateAcct = new AmAccountMainInvestorInfo();
                            updateAcct.setId(acct.getId());
                            updateAcct.setCustomerId(acct.getCustomerId());
                            updateAcct.setTenantId(acct.getTenantId());
                            updateAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
                            return updateAcct;
                        }
                ).collect(Collectors.toList());
                delqSaveBean.setUpdateAcctList(updateList);
            }

            //更新还款计划   当期逾期金额
            updatePlan.setOverDueAmount(delq.getTotalAmountDue());
            updatePlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_2);
            //更新订单
            AmLoanAccountInvestorInfo updateLoan = new AmLoanAccountInvestorInfo();
            updateLoan.setId(amLoanAccountInfo.getId());
            updateLoan.setTenantId(amLoanAccountInfo.getTenantId());
            updateLoan.setCustomerId(amLoanAccountInfo.getCustomerId());
            //状态
            updateLoan.setAccountStatus(TransBizConstant.LOAN_STATUS_2);
            //连续逾期期数
            updateLoan.setContinueOverDueTenor(amLoanAccountInfo.getContinueOverDueTenor() + 1);
            //总逾期期数
            updateLoan.setTotalOverDueTenor(amLoanAccountInfo.getTotalOverDueTenor() + 1);
            delqSaveBean.setUpdateLoan(updateLoan);
        } else {//当前还款计划为逾期状态   更新延滞账户
            AmDelinquencyInvestorInfo amDelinquencyInfo = bean.getDelqAcct();
            Integer lastDelqDays = amDelinquencyInfo.getDelqDays();
            AmDelinquencyInvestorInfo updateDelq = new AmDelinquencyInvestorInfo();
            updateDelq.setId(amDelinquencyInfo.getId());
            updateDelq.setCustomerId(customerId);
            updateDelq.setTenantId(tenantId);
            updateDelq.setLastDelqDays(lastDelqDays);
            updateDelq.setDelqDays(delqDays);
            delqSaveBean.setUpdateDelq(updateDelq);
        }
        delqSaveBean.setUpdatePlan(updatePlan);
        return delqSaveBean;
    }

    /**
     * 处理当期无欠款订单
     *
     * @param dealDelqBean
     * @return
     */
    private InvestorDelqSaveBean dealNoDebt(InvestorDealDelqBean dealDelqBean) {
        AmLoanMainInvestorInfo amLoanMainInfo = dealDelqBean.getLoanMain();
        AmLoanAccountInvestorInfo amLoanAccountInfo = dealDelqBean.getLoanAcct();
        AmRepaymentPlanInvestorInfo repaymentPlanInfo = dealDelqBean.getRepaymentPlanInfo();
        List<AmAccountMainInvestorInfo> acctList = dealDelqBean.getAcctList();
        Date businessDate = dealDelqBean.getBusinessDate();

        //欠款计算
        BigDecimal debtAmt = repaymentPlanInfo.getTotalAmount().subtract(repaymentPlanInfo.getRepayPrincipal())
                .subtract(repaymentPlanInfo.getRepayInterest()).subtract(repaymentPlanInfo.getRepayFee());
        if (debtAmt.compareTo(BigDecimal.ZERO) > 0) {
            return null;
        }

        InvestorDelqSaveBean delqSaveBean = new InvestorDelqSaveBean();
        AmRepaymentPlanInvestorInfo updatePlan = new AmRepaymentPlanInvestorInfo();
        updatePlan.setId(repaymentPlanInfo.getId());
        updatePlan.setCustomerId(repaymentPlanInfo.getCustomerId());
        updatePlan.setTenantId(repaymentPlanInfo.getTenantId());
        updatePlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_8);
        updatePlan.setPaymentDueDate(businessDate);
        delqSaveBean.setUpdatePlan(updatePlan);

        AmLoanAccountInvestorInfo updateLoan = new AmLoanAccountInvestorInfo();
        updateLoan.setId(amLoanAccountInfo.getId());
        updateLoan.setCustomerId(amLoanAccountInfo.getCustomerId());
        updateLoan.setTenantId(amLoanAccountInfo.getTenantId());
        updateLoan.setPayedTenor(amLoanAccountInfo.getPayedTenor() + 1);
        if (repaymentPlanInfo.getBillingTenor().intValue() == amLoanMainInfo.getTotalTenor().intValue()) {
            updateLoan.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_8);
            updateLoan.setPayoffDate(DateUtils.formatDate(businessDate));
        }
        delqSaveBean.setUpdateLoan(updateLoan);
        //更新交易账户
        if (CollectionUtils.isNotEmpty(acctList)) {
            List<AmAccountMainInvestorInfo> updateList = acctList.stream().map(
                    acct -> {
                        AmAccountMainInvestorInfo updateAcct = new AmAccountMainInvestorInfo();
                        updateAcct.setId(acct.getId());
                        updateAcct.setCustomerId(acct.getCustomerId());
                        updateAcct.setTenantId(acct.getTenantId());
                        updateAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_8);
                        return updateAcct;
                    }
            ).collect(Collectors.toList());
            delqSaveBean.setUpdateAcctList(updateList);
        }
        return delqSaveBean;

    }

    /**
     * 延滞外转列处理 会计状态升级，转非应计，五级分类升级
     *
     * @param dealTransOutBean
     * @return InvestorDelqTransOutSaveBean 延滞会计处理更新信息
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-26
     */
    @Override
    public InvestorDelqTransOutSaveBean dealDelqTransOut(InvestorDealTransOutBean dealTransOutBean) throws TxnException {
        InvestorDelqTransOutSaveBean saveBean = new InvestorDelqTransOutSaveBean();
        AmLoanAccountInvestorInfo loanAcct = dealTransOutBean.getLoanAcct();
        Date businessDate = dealTransOutBean.getBusinessDate();
        String investorLoanId = loanAcct.getInvestorLoanId();
        String tenantId = loanAcct.getTenantId();


        //查询逾期还款计划
        List<AmRepaymentPlanInvestorInfo> planInfoList = dealTransOutBean.getPlanInfoList().stream()
                .filter(planInfo -> investorLoanId.equals(planInfo.getInvestorLoanId()))
                .filter(planInfo -> Arrays.asList(com.jrx.anytxn.transaction.constant.TransBizConstant.LOAN_PLAN_STATUS_1, com.jrx.anytxn.transaction.constant.TransBizConstant.LOAN_PLAN_STATUS_2).contains(planInfo.getPlanStatus()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(planInfoList)) {
            logger.info("出资方订单号[{}]DelqTransOut处理还款计划为空", investorLoanId);
            throw new TxnException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getUserTips());
        }

        //最大逾期天数
        int delqMaxDays = planInfoList.stream()
                .map(AmRepaymentPlanInvestorInfo::getDelqDays)
                .max(Integer::compareTo)
                .orElse(0);

        AmLoanMainInvestorInfo amLoanMainInfo = dealTransOutBean.getLoanMain();
        //延滞参数
        DelqParamBean delqParamBean = dealDelqService.buildDqlqAccountBean(tenantId, amLoanMainInfo.getDelqTableId());

        List<InvestorTransferBean> transferBeanList = new ArrayList<>();
        planInfoList.forEach(
                plan -> {
                    int delqDays = plan.getDelqDays();
                    int billingTenor = plan.getBillingTenor();
                    //交易账户外转列处理 会计状态升级，转非应计，五级分类升级
                    List<AmAccountMainInvestorInfo> acctList = dealTransOutBean.getAcctList().stream()
                            .filter(acct -> investorLoanId.equals(acct.getInvestorLoanId()))
                            .filter(acct -> billingTenor == acct.getBillingTenor())
                            .filter(acct -> Arrays.asList(TransBizConstant.ACCOUNT_TYPE_04, TransBizConstant.ACCOUNT_TYPE_06,
                                    TransBizConstant.ACCOUNT_TYPE_11, TransBizConstant.ACCOUNT_TYPE_12).contains(acct.getAccountType()))
                            .filter(acct -> Arrays.asList(TransBizConstant.ACCOUNT_STATUS_1, TransBizConstant.ACCOUNT_STATUS_2).contains(acct.getAccountStatus()))
                            .collect(Collectors.toList());

                    if (CollectionUtils.isNotEmpty(acctList)) {
                        acctList.stream()
                                .map(acct -> new InvestorTransferBean<>(acct).setAccountType(acct.getAccountType()).setDelqDays(delqDays))
                                .forEach(transferBeanList::add);
                    }

                    //累计账户外转列处理 会计状态升级，转非应计，五级分类升级
                    List<AmInterestAccrualInvestorInfo> accuAcctList = dealTransOutBean.getAccuAcctList().stream()
                            .filter(acct -> billingTenor == acct.getBillingTenor())
                            .filter(acct -> investorLoanId.equals(acct.getInvestorLoanId()))
                            .filter(acct -> TransBizConstant.INTEREST_ACCRUAL_STATUS_1.equals(acct.getAccountStatus()))
                            .collect(Collectors.toList());

                    if (CollectionUtils.isNotEmpty(accuAcctList)) {
                        accuAcctList.stream()
                                .map(accuAcct -> new InvestorTransferBean<>(accuAcct).setAccountType(accuAcct.getAccountType()).setDelqDays(delqDays))
                                .forEach(transferBeanList::add);
                    }
                }

        );

        //订单外转列处理 会计状态升级，转非应计，五级分类升级
        transferBeanList.add(new InvestorTransferBean<>(loanAcct).setAccountType(TransBizConstant.ACCOUNT_TYPE_05).setDelqDays(delqMaxDays));
        UncheckedFunction<InvestorTransferBean, InvestorTransferSaveBean> transfer = transferBean -> {
            transferBean.setDelqParamBean(delqParamBean).setMaxDelqDays(delqMaxDays).setBussinessDate(businessDate).setAmLoanMainInfo(amLoanMainInfo);
            String transferMethod = delqParamBean.getDelqNonAccrualBeanMap().get(transferBean.getAccountType()).getTransferMethod();
            InvestorTransferBean trans = strategySelector.selectMethodStrategy(transferMethod).transferOut(transferBean);
            return strategySelector.selectTypeStrategy(transferBean.getTransferObject()).transferOut(trans);
        };

        transferBeanList.stream()
                .map(CollectorsUtils.tranToUncheck(transfer))
                .filter(Objects::nonNull)
                .forEach(saveBean.getTransferSaveBeanList()::add);


        //记录订单形态转移流水
        List<TlInvestorLoanChange> loanChangList = new ArrayList<>();
        List<TlInvestorLoanChange> loanChangAllList = saveBean.getTransferSaveBeanList().stream().map(InvestorTransferSaveBean::getLoanChangeList)
                .filter(CollectionUtils::isNotEmpty).map(List::iterator).map(Iterator::next).collect(Collectors.toList());
        Map<String, List<TlInvestorLoanChange>> loanChangeMap = loanChangAllList.stream().collect(Collectors.groupingBy(TlInvestorLoanChange::getEventCode));
        loanChangeMap.forEach(
                (k, v) -> {
                    TlInvestorLoanChange loanChange = loanChangeService.genarateLoanChange(loanAcct, businessDate);
                    v.forEach(loanChange::add);
                    logger.info("形态转移流水TlInvestorLoanChange:{}", BeanUtils.toMap(loanChange));
                    loanChangList.add(loanChange);
                }
        );

        saveBean.setLoanChangeList(loanChangList);
        return saveBean;
    }

    /**
     * 延滞内转列处理 会计状态降级，转应计，五级分类降级
     *
     * @param dealTransInBean
     * @return InvestorDelqTransInSaveBean 延滞会计处理更新信息
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-26
     */
    @Override
    public InvestorDelqTransInSaveBean dealDelqTransIn(InvestorDealTransInBean dealTransInBean) throws TxnException {
        InvestorDelqTransInSaveBean saveBean = new InvestorDelqTransInSaveBean();
        AmLoanAccountInvestorInfo loanAcct = dealTransInBean.getLoanAcct();
        Date businessDate = dealTransInBean.getBusinessDate();
        String investorLoanId = loanAcct.getInvestorLoanId();
        String tenantId = loanAcct.getTenantId();

        //查询逾期还款计划
        List<AmRepaymentPlanInvestorInfo> planInfoList = dealTransInBean.getPlanInfoList().stream()
                .filter(planInfo -> investorLoanId.equals(planInfo.getInvestorLoanId()))
                .filter(planInfo -> Arrays.asList(TransBizConstant.LOAN_PLAN_STATUS_1, TransBizConstant.LOAN_PLAN_STATUS_2).contains(planInfo.getPlanStatus()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(planInfoList)) {
            logger.info("DelqTransIn处理还款计划为空");
            return null;
        }

        //最大逾期天数
        int delqMaxDays = planInfoList.stream()
                .map(AmRepaymentPlanInvestorInfo::getDelqDays)
                .max(Integer::compareTo)
                .orElse(0);

        AmLoanMainInvestorInfo amLoanMainInfo = dealTransInBean.getLoanMain();
        //延滞参数
        DelqParamBean delqParamBean = dealDelqService.buildDqlqAccountBean(tenantId, amLoanMainInfo.getDelqTableId());

        List<InvestorTransferBean> transferBeanList = new ArrayList<>();
        planInfoList.forEach(
                plan -> {
                    int delqDays = plan.getDelqDays();
                    int billingTenor = plan.getBillingTenor();
                    //交易账户内转列处理 会计状态将级，转应计，五级分类降级
                    List<AmAccountMainInvestorInfo> acctList = dealTransInBean.getAcctList().stream()
                            .filter(acct -> investorLoanId.equals(acct.getInvestorLoanId()))
                            .filter(acct -> billingTenor == acct.getBillingTenor())
                            .filter(acct -> Arrays.asList(TransBizConstant.ACCOUNT_TYPE_04, TransBizConstant.ACCOUNT_TYPE_06,
                                    TransBizConstant.ACCOUNT_TYPE_11, TransBizConstant.ACCOUNT_TYPE_12).contains(acct.getAccountType()))
                            .filter(acct -> Arrays.asList(TransBizConstant.ACCOUNT_STATUS_1, TransBizConstant.ACCOUNT_STATUS_2).contains(acct.getAccountStatus()))
                            .collect(Collectors.toList());

                    if (CollectionUtils.isNotEmpty(acctList)) {
                        acctList.stream()
                                .map(acct -> new InvestorTransferBean<>(acct).setAccountType(acct.getAccountType()).setDelqDays(delqDays))
                                .forEach(transferBeanList::add);
                    }

                    //累计账户内转列处理 会计状态将级，转应计，五级分类降级
                    List<AmInterestAccrualInvestorInfo> accuAcctList = dealTransInBean.getAccuAcctList().stream()
                            .filter(acct -> billingTenor == acct.getBillingTenor())
                            .filter(acct -> investorLoanId.equals(acct.getInvestorLoanId()))
                            .filter(acct -> TransBizConstant.INTEREST_ACCRUAL_STATUS_1.equals(acct.getAccountStatus()))
                            .collect(Collectors.toList());

                    if (CollectionUtils.isNotEmpty(accuAcctList)) {
                        accuAcctList.stream()
                                .map(accuAcct -> new InvestorTransferBean<>(accuAcct).setAccountType(accuAcct.getAccountType()).setDelqDays(delqDays))
                                .forEach(transferBeanList::add);
                    }
                }

        );

        //订单内转列处理 会计状态将级，转应计，五级分类降级
        transferBeanList.add(new InvestorTransferBean<>(loanAcct).setAccountType(TransBizConstant.ACCOUNT_TYPE_05).setDelqDays(delqMaxDays));
        UncheckedFunction<InvestorTransferBean, InvestorTransferSaveBean> transfer = transferBean -> {
            transferBean.setDelqParamBean(delqParamBean).setMaxDelqDays(delqMaxDays).setBussinessDate(businessDate).setAmLoanMainInfo(amLoanMainInfo);
            String transferMethod = delqParamBean.getDelqNonAccrualBeanMap().get(transferBean.getAccountType()).getTransferMethod();
            InvestorTransferBean trans = strategySelector.selectMethodStrategy(transferMethod).transferIn(transferBean);
            return strategySelector.selectTypeStrategy(transferBean.getTransferObject()).transferIn(trans);
        };

        transferBeanList.stream()
                .map(CollectorsUtils.tranToUncheck(transfer))
                .filter(Objects::nonNull)
                .forEach(saveBean.getTransferSaveBeanList()::add);

        //记录订单形态转移流水
        List<TlInvestorLoanChange> loanChangList = new ArrayList<>();
        List<TlInvestorLoanChange> loanChangAllList = saveBean.getTransferSaveBeanList().stream().map(InvestorTransferSaveBean::getLoanChangeList)
                .filter(CollectionUtils::isNotEmpty).map(List::iterator).map(Iterator::next).collect(Collectors.toList());
        Map<String, List<TlInvestorLoanChange>> loanChangeMap = loanChangAllList.stream().collect(Collectors.groupingBy(TlInvestorLoanChange::getEventCode));
        loanChangeMap.forEach(
                (k, v) -> {
                    TlInvestorLoanChange loanChange = loanChangeService.genarateLoanChange(loanAcct, businessDate);
                    v.forEach(loanChange::add);
                    logger.info("形态转移流水TlInvestorLoanChange:{}", BeanUtils.toMap(loanChange));
                    loanChangList.add(loanChange);
                }
        );

        saveBean.setLoanChangeList(loanChangList);
        return saveBean;
    }
}
